import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import {
  NovelParseTask,
  TaskStatus,
} from '../entities/novel-parse-task.entity';
import { InjectQueue } from '@nestjs/bull';
import { Queue } from 'bull';
import { NovelParseJobData } from '../processors/novel-parse.processor';

@Injectable()
export class TaskRecoveryService implements OnModuleInit {
  private readonly logger = new Logger(TaskRecoveryService.name);

  constructor(
    @InjectRepository(NovelParseTask)
    private readonly taskRepository: Repository<NovelParseTask>,
    @InjectQueue('novel-parse')
    private readonly novelParseQueue: Queue,
  ) {}

  /**
   * 模块初始化时执行任务恢复
   */
  async onModuleInit() {
    this.logger.log('启动任务恢复服务...');
    await this.recoverStuckTasks();
  }

  /**
   * 恢复卡住的任务
   */
  async recoverStuckTasks(): Promise<void> {
    try {
      const now = new Date();
      const stuckTimeout = 2 * 60 * 1000; // 2分钟超时

      // 查找可能卡住的任务
      const stuckTasks = await this.taskRepository.find({
        where: {
          status: TaskStatus.PROCESSING,
        },
      });

      let recoveredCount = 0;

      for (const task of stuckTasks) {
        if (task.startedAt) {
          const processingTime = now.getTime() - task.startedAt.getTime();

          // 如果处理时间超过阈值，认为是服务重启导致的僵尸任务
          if (processingTime > stuckTimeout) {
            this.logger.warn(
              `恢复僵尸任务: ${task.taskId}, ` +
                `小说: ${task.novelTitle}, ` +
                `已处理: ${Math.round(processingTime / 1000)}秒`,
            );

            // 重置任务状态
            await this.taskRepository.update(task.id, {
              status: TaskStatus.PENDING,
              errorMessage: '服务重启后自动恢复',
              startedAt: null,
              // 不增加重试次数
            });

            // 重新加入队列
            const jobData: NovelParseJobData = {
              taskId: task.taskId,
              novelId: task.novelId!,
              originalUrl: task.originalUrl!,
              novelTitle: task.novelTitle!,
              platform: task.taskData?.platform || 'qidian',
            };

            await this.novelParseQueue.add('chapter-content', jobData, {
              attempts: 3,
              backoff: {
                type: 'exponential',
                delay: 2000,
              },
              removeOnComplete: 10,
              removeOnFail: 50,
            });

            recoveredCount++;
          }
        }
      }

      if (recoveredCount > 0) {
        this.logger.log(`成功恢复 ${recoveredCount} 个卡住的任务`);
      } else {
        this.logger.log('没有发现需要恢复的任务');
      }
    } catch (error) {
      this.logger.error('任务恢复失败:', error);
    }
  }

  /**
   * 手动触发任务恢复
   */
  async manualRecovery(): Promise<{ recovered: number; message: string }> {
    await this.recoverStuckTasks();
    return {
      recovered: 0, // 这里可以返回实际恢复的数量
      message: '任务恢复完成',
    };
  }
}
